home *** CD-ROM | disk | FTP | other *** search
/ Language/OS - Multiplatform Resource Library / LANGUAGE OS.iso / lisp / wgdb-42.lha / wgdb-4.2 / gdb / mips-tdep.c < prev    next >
C/C++ Source or Header  |  1992-09-11  |  22KB  |  686 lines

  1. /* Work with core dump and executable files, for GDB on MIPS. 
  2.    This code would be in core.c if it weren't machine-dependent. */
  3.  
  4. /* Low level interface to ptrace, for GDB when running under Unix.
  5.    Copyright (C) 1988, 1989, 1990  Free Software Foundation, Inc.
  6.    Contributed by Alessandro Forin(af@cs.cmu.edu) at CMU
  7.    and by Per Bothner(bothner@cs.wisc.edu) at U.Wisconsin.
  8.  
  9. This file is part of GDB.
  10.  
  11. This program is free software; you can redistribute it and/or modify
  12. it under the terms of the GNU General Public License as published by
  13. the Free Software Foundation; either version 2 of the License, or
  14. (at your option) any later version.
  15.  
  16. This program is distributed in the hope that it will be useful,
  17. but WITHOUT ANY WARRANTY; without even the implied warranty of
  18. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  19. GNU General Public License for more details.
  20.  
  21. You should have received a copy of the GNU General Public License
  22. along with this program; if not, write to the Free Software
  23. Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.  */
  24.  
  25. #include <stdio.h>
  26. #include "defs.h"
  27. #include "param.h"
  28. #include "frame.h"
  29. #include "inferior.h"
  30. #include "symtab.h"
  31. #include "value.h"
  32. #include "gdbcmd.h"
  33. #include "language.h"
  34.  
  35. #ifdef USG
  36. #include <sys/types.h>
  37. #endif
  38.  
  39. #include <sys/param.h>
  40. #include <sys/dir.h>
  41. #include <signal.h>
  42. #include <sys/ioctl.h>
  43.  
  44. #include "gdbcore.h"
  45.  
  46. #ifndef    MIPSMAGIC
  47. #ifdef MIPSEL
  48. #define MIPSMAGIC    MIPSELMAGIC
  49. #else
  50. #define MIPSMAGIC    MIPSEBMAGIC
  51. #endif
  52. #endif
  53.  
  54. #define VM_MIN_ADDRESS (unsigned)0x400000
  55.  
  56. #include <sys/user.h>        /* After a.out.h  */
  57. #include <sys/file.h>
  58. #include <sys/stat.h>
  59.  
  60.  
  61. #define PROC_LOW_ADDR(proc) ((proc)->adr) /* least address */
  62. #define PROC_HIGH_ADDR(proc) ((proc)->pad2) /* upper address bound */
  63. #define PROC_FRAME_OFFSET(proc) ((proc)->framesize)
  64. #define PROC_FRAME_REG(proc) ((proc)->framereg)
  65. #define PROC_REG_MASK(proc) ((proc)->regmask)
  66. #define PROC_FREG_MASK(proc) ((proc)->fregmask)
  67. #define PROC_REG_OFFSET(proc) ((proc)->regoffset)
  68. #define PROC_FREG_OFFSET(proc) ((proc)->fregoffset)
  69. #define PROC_PC_REG(proc) ((proc)->pcreg)
  70. #define PROC_SYMBOL(proc) (*(struct symbol**)&(proc)->isym)
  71. #define _PROC_MAGIC_ 0x0F0F0F0F
  72. #define PROC_DESC_IS_DUMMY(proc) ((proc)->isym == _PROC_MAGIC_)
  73. #define SET_PROC_DESC_IS_DUMMY(proc) ((proc)->isym = _PROC_MAGIC_)
  74.  
  75. struct linked_proc_info
  76. {
  77.   struct mips_extra_func_info info;
  78.   struct linked_proc_info *next;
  79. } * linked_proc_desc_table = NULL;
  80.  
  81.  
  82. #define READ_FRAME_REG(fi, regno) read_next_frame_reg((fi)->next, regno)
  83.  
  84. int
  85. read_next_frame_reg(fi, regno)
  86.      FRAME fi;
  87.      int regno;
  88. {
  89. #define SIGFRAME_BASE   sizeof(struct sigcontext)
  90. #define SIGFRAME_PC_OFF (-SIGFRAME_BASE+ 2*sizeof(int))
  91. #define SIGFRAME_SP_OFF (-SIGFRAME_BASE+32*sizeof(int))
  92. #define SIGFRAME_RA_OFF (-SIGFRAME_BASE+34*sizeof(int))
  93.   for (; fi; fi = fi->next)
  94.       if (in_sigtramp(fi->pc, 0)) {
  95.       /* No idea if this code works. --PB. */
  96.       int offset;
  97.       if (regno == PC_REGNUM) offset = SIGFRAME_PC_OFF;
  98.       else if (regno == RA_REGNUM) offset = SIGFRAME_RA_OFF;
  99.       else if (regno == SP_REGNUM) offset = SIGFRAME_SP_OFF;
  100.       else return 0;
  101.       return read_memory_integer(fi->frame + offset, 4);
  102.       }
  103.       else if (regno == SP_REGNUM) return fi->frame;
  104.       else if (fi->saved_regs->regs[regno])
  105.     return read_memory_integer(fi->saved_regs->regs[regno], 4);
  106.   return read_register(regno);
  107. }
  108.  
  109. int
  110. mips_frame_saved_pc(frame)
  111.      FRAME frame;
  112. {
  113.   mips_extra_func_info_t proc_desc = (mips_extra_func_info_t)frame->proc_desc;
  114.   int pcreg = proc_desc ? PROC_PC_REG(proc_desc) : RA_REGNUM;
  115.   if (proc_desc && PROC_DESC_IS_DUMMY(proc_desc))
  116.       return read_memory_integer(frame->frame - 4, 4);
  117. #if 0
  118.   /* If in the procedure prologue, RA_REGNUM might not have been saved yet.
  119.    * Assume non-leaf functions start with:
  120.    *    addiu $sp,$sp,-frame_size
  121.    *    sw $ra,ra_offset($sp)
  122.    * This if the pc is pointing at either of these instructions,
  123.    * then $ra hasn't been trashed.
  124.    * If the pc has advanced beyond these two instructions,
  125.    * then $ra has been saved.
  126.    * critical, and much more complex. Handling $ra is enough to get
  127.    * a stack trace, but some register values with be wrong.
  128.    */
  129.   if (frame->proc_desc && frame->pc < PROC_LOW_ADDR(proc_desc) + 8)
  130.       return read_register(pcreg);
  131. #endif
  132.   return read_next_frame_reg(frame, pcreg);
  133. }
  134.  
  135. static struct mips_extra_func_info temp_proc_desc;
  136. static struct frame_saved_regs temp_saved_regs;
  137.  
  138. CORE_ADDR heuristic_proc_start(pc)
  139.     CORE_ADDR pc;
  140. {
  141.  
  142.     CORE_ADDR start_pc = pc;
  143.     CORE_ADDR fence = start_pc - 10000;
  144.     if (fence < VM_MIN_ADDRESS) fence = VM_MIN_ADDRESS;
  145.     /* search back for previous return */
  146.     for (start_pc -= 4; ; start_pc -= 4)
  147.     if (start_pc < fence) return 0; 
  148.     else if (ABOUT_TO_RETURN(start_pc))
  149.         break;
  150.  
  151.     start_pc += 8; /* skip return, and its delay slot */
  152. #if 0
  153.     /* skip nops (usually 1) 0 - is this */
  154.     while (start_pc < pc && read_memory_integer (start_pc, 4) == 0)
  155.     start_pc += 4;
  156. #endif
  157.     return start_pc;
  158. }
  159.  
  160. mips_extra_func_info_t
  161. heuristic_proc_desc(start_pc, limit_pc, next_frame)
  162.     CORE_ADDR start_pc, limit_pc;
  163.     FRAME next_frame;
  164. {
  165.     CORE_ADDR sp = next_frame ? next_frame->frame : read_register (SP_REGNUM);
  166.     CORE_ADDR cur_pc;
  167.     int frame_size;
  168.     int has_frame_reg = 0;
  169.     int reg30; /* Value of $r30. Used by gcc for frame-pointer */
  170.     unsigned long reg_mask = 0;
  171.  
  172.     if (start_pc == 0) return NULL;
  173.     bzero(&temp_proc_desc, sizeof(temp_proc_desc));
  174.     bzero(&temp_saved_regs, sizeof(struct frame_saved_regs));
  175.     if (start_pc + 200 < limit_pc) limit_pc = start_pc + 200;
  176.   restart:
  177.     frame_size = 0;
  178.     for (cur_pc = start_pc; cur_pc < limit_pc; cur_pc += 4) {
  179.     unsigned long word;
  180.     int status;
  181.  
  182.     status = read_memory_nobpt (cur_pc, &word, 4); 
  183.     if (status) memory_error (status, cur_pc); 
  184.     if ((word & 0xFFFF0000) == 0x27bd0000) /* addiu $sp,$sp,-i */
  185.         frame_size += (-word) & 0xFFFF;
  186.     else if ((word & 0xFFFF0000) == 0x23bd0000) /* addu $sp,$sp,-i */
  187.         frame_size += (-word) & 0xFFFF;
  188.     else if ((word & 0xFFE00000) == 0xafa00000) { /* sw reg,offset($sp) */
  189.         int reg = (word & 0x001F0000) >> 16;
  190.         reg_mask |= 1 << reg;
  191.         temp_saved_regs.regs[reg] = sp + (short)word;
  192.     }
  193.     else if ((word & 0xFFFF0000) == 0x27be0000) { /* addiu $30,$sp,size */
  194.         if ((unsigned short)word != frame_size)
  195.         reg30 = sp + (unsigned short)word;
  196.         else if (!has_frame_reg) {
  197.         int alloca_adjust;
  198.         has_frame_reg = 1;
  199.         reg30 = read_next_frame_reg(next_frame, 30);
  200.         alloca_adjust = reg30 - (sp + (unsigned short)word);
  201.         if (alloca_adjust > 0) {
  202.             /* FP > SP + frame_size. This may be because
  203.             /* of an alloca or somethings similar.
  204.              * Fix sp to "pre-alloca" value, and try again.
  205.              */
  206.             sp += alloca_adjust;
  207.             goto restart;
  208.         }
  209.         }
  210.     }
  211.     else if ((word & 0xFFE00000) == 0xafc00000) { /* sw reg,offset($30) */
  212.         int reg = (word & 0x001F0000) >> 16;
  213.         reg_mask |= 1 << reg;
  214.         temp_saved_regs.regs[reg] = reg30 + (short)word;
  215.     }
  216.     }
  217.     if (has_frame_reg) {
  218.     PROC_FRAME_REG(&temp_proc_desc) = 30;
  219.     PROC_FRAME_OFFSET(&temp_proc_desc) = 0;
  220.     }
  221.     else {
  222.     PROC_FRAME_REG(&temp_proc_desc) = SP_REGNUM;
  223.     PROC_FRAME_OFFSET(&temp_proc_desc) = frame_size;
  224.     }
  225.     PROC_REG_MASK(&temp_proc_desc) = reg_mask;
  226.     PROC_PC_REG(&temp_proc_desc) = RA_REGNUM;
  227.     return &temp_proc_desc;
  228. }
  229.  
  230. mips_extra_func_info_t
  231. find_proc_desc(pc, next_frame)
  232.     CORE_ADDR pc;
  233.     FRAME next_frame;
  234. {
  235.   mips_extra_func_info_t proc_desc;
  236.   extern struct block *block_for_pc();
  237.   struct block   *b = block_for_pc(pc);
  238.  
  239.   struct symbol *sym =
  240.       b ? lookup_symbol(".gdbinfo.", b, LABEL_NAMESPACE, 0, NULL) : NULL;
  241.   if (sym != NULL)
  242.     {
  243.     /* IF this is the topmost frame AND
  244.      * (this proc does not have debugging information OR
  245.      * the PC is in the procedure prologue)
  246.      * THEN create a "hueristic" proc_desc (by analyzing
  247.      * the actual code) to replace the "official" proc_desc.
  248.      */
  249.     proc_desc = (struct mips_extra_func_info *)sym->value.value;
  250.     if (next_frame == NULL) {
  251.         struct symtab_and_line val;
  252.         struct symbol *proc_symbol =
  253.         PROC_DESC_IS_DUMMY(proc_desc) ? 0 : PROC_SYMBOL(proc_desc);
  254.         if (proc_symbol) {
  255.         val = find_pc_line (BLOCK_START
  256.                     (SYMBOL_BLOCK_VALUE(proc_symbol)),
  257.                     0);
  258.         val.pc = val.end ? val.end : pc;
  259.         }
  260.         if (!proc_symbol || pc < val.pc) {
  261.         mips_extra_func_info_t found_heuristic =
  262.             heuristic_proc_desc(PROC_LOW_ADDR(proc_desc),
  263.                     pc, next_frame);
  264.         if (found_heuristic) proc_desc = found_heuristic;
  265.         }
  266.     }
  267.     }
  268.   else
  269.     {
  270.       register struct linked_proc_info *link;
  271.       for (link = linked_proc_desc_table; link; link = link->next)
  272.       if (PROC_LOW_ADDR(&link->info) <= pc
  273.           && PROC_HIGH_ADDR(&link->info) > pc)
  274.           return &link->info;
  275.       proc_desc =
  276.       heuristic_proc_desc(heuristic_proc_start(pc), pc, next_frame);
  277.     }
  278.   return proc_desc;
  279. }
  280.  
  281. mips_extra_func_info_t cached_proc_desc;
  282.  
  283. FRAME_ADDR mips_frame_chain(frame)
  284.     FRAME frame;
  285. {
  286.     extern CORE_ADDR startup_file_start;    /* From blockframe.c */
  287.     mips_extra_func_info_t proc_desc;
  288.     CORE_ADDR saved_pc = FRAME_SAVED_PC(frame);
  289.     if (startup_file_start)
  290.       { /* has at least the __start symbol */
  291.     if (saved_pc == 0 || !outside_startup_file (saved_pc)) return 0;
  292.       }
  293.     else
  294.       { /* This hack depends on the internals of __start. */
  295.     /* We also assume the breakpoints are *not* inserted */
  296.         if (saved_pc == 0
  297.         || read_memory_integer (saved_pc + 8, 4) & 0xFC00003F == 0xD)
  298.         return 0;  /* break */
  299.       }
  300.     proc_desc = find_proc_desc(saved_pc, frame);
  301.     if (!proc_desc) return 0;
  302.     cached_proc_desc = proc_desc;
  303.     return read_next_frame_reg(frame, PROC_FRAME_REG(proc_desc))
  304.     + PROC_FRAME_OFFSET(proc_desc);
  305. }
  306.  
  307. void
  308. init_extra_frame_info(fci)
  309.      struct frame_info *fci;
  310. {
  311.   extern struct obstack frame_cache_obstack;
  312.   /* Use proc_desc calculated in frame_chain */
  313.   mips_extra_func_info_t proc_desc = fci->next ? cached_proc_desc :
  314.       find_proc_desc(fci->pc, fci->next);
  315.   fci->saved_regs = (struct frame_saved_regs*)
  316.     obstack_alloc (&frame_cache_obstack, sizeof(struct frame_saved_regs));
  317.   bzero(fci->saved_regs, sizeof(struct frame_saved_regs));
  318.   fci->proc_desc =
  319.       proc_desc == &temp_proc_desc ? (char*)NULL : (char*)proc_desc;
  320.   if (proc_desc)
  321.     {
  322.       int ireg;
  323.       CORE_ADDR reg_position;
  324.       unsigned long mask;
  325.       /* r0 bit means kernel trap */
  326.       int kernel_trap = PROC_REG_MASK(proc_desc) & 1;
  327.  
  328.       /* Fixup frame-pointer - only needed for top frame */
  329.       /* This may not be quite right, if procedure has a real frame register */
  330.       if (fci->pc == PROC_LOW_ADDR(proc_desc))
  331.       fci->frame = read_register (SP_REGNUM);
  332.       else
  333.       fci->frame = READ_FRAME_REG(fci, PROC_FRAME_REG(proc_desc))
  334.           + PROC_FRAME_OFFSET(proc_desc);
  335.  
  336.       if (proc_desc == &temp_proc_desc)
  337.       *fci->saved_regs = temp_saved_regs;
  338.       else
  339.       {
  340.       /* find which general-purpose registers were saved */
  341.       reg_position = fci->frame + PROC_REG_OFFSET(proc_desc);
  342.       mask = kernel_trap ? 0xFFFFFFFF : PROC_REG_MASK(proc_desc);
  343.       for (ireg= 31; mask; --ireg, mask <<= 1)
  344.           if (mask & 0x80000000)
  345.           {
  346.           fci->saved_regs->regs[ireg] = reg_position;
  347.           reg_position -= 4;
  348.           }
  349.       /* find which floating-point registers were saved */
  350.       reg_position = fci->frame + PROC_FREG_OFFSET(proc_desc);
  351.       /* The freg_offset points to where the first *double* register is saved.
  352.        * So skip to the high-order word. */
  353.       reg_position += 4;
  354.       mask = kernel_trap ? 0xFFFFFFFF : PROC_FREG_MASK(proc_desc);
  355.       for (ireg = 31; mask; --ireg, mask <<= 1)
  356.           if (mask & 0x80000000)
  357.           {
  358.           fci->saved_regs->regs[32+ireg] = reg_position;
  359.           reg_position -= 4;
  360.           }
  361.       }
  362.  
  363.       /* hack: if argument regs are saved, guess these contain args */
  364.       if ((PROC_REG_MASK(proc_desc) & 0xF0) == 0) fci->num_args = -1;
  365.       else if ((PROC_REG_MASK(proc_desc) & 0x80) == 0) fci->num_args = 4;
  366.       else if ((PROC_REG_MASK(proc_desc) & 0x40) == 0) fci->num_args = 3;
  367.       else if ((PROC_REG_MASK(proc_desc) & 0x20) == 0) fci->num_args = 2;
  368.       else if ((PROC_REG_MASK(proc_desc) & 0x10) == 0) fci->num_args = 1;
  369.  
  370.       fci->saved_regs->regs[PC_REGNUM] = fci->saved_regs->regs[RA_REGNUM];
  371.     }
  372.   if (fci->next == 0)
  373.       supply_register(FP_REGNUM, &fci->frame);
  374. }
  375.  
  376.  
  377. CORE_ADDR mips_push_arguments(nargs, args, sp, struct_return, struct_addr)
  378.   int nargs;
  379.   value *args;
  380.   CORE_ADDR sp;
  381.   int struct_return;
  382.   CORE_ADDR struct_addr;
  383. {
  384.   CORE_ADDR buf;
  385.   register i;
  386.   int accumulate_size = struct_return ? 4 : 0;
  387.   struct mips_arg { char *contents; int len; int offset; };
  388.   struct mips_arg *mips_args =
  389.       (struct mips_arg*)alloca(nargs * sizeof(struct mips_arg));
  390.   register struct mips_arg *m_arg;
  391.   for (i = 0, m_arg = mips_args; i < nargs; i++, m_arg++) {
  392.     extern value value_arg_coerce();
  393.     value arg = value_arg_coerce (args[i]);
  394.     m_arg->len = TYPE_LENGTH (VALUE_TYPE (arg));
  395.     /* This entire mips-specific routine is because doubles must be aligned
  396.      * on 8-byte boundaries. It still isn't quite right, because MIPS decided
  397.      * to align 'struct {int a, b}' on 4-byte boundaries (even though this
  398.      * breaks their varargs implementation...). A correct solution
  399.      * requires an simulation of gcc's 'alignof' (and use of 'alignof'
  400.      * in stdarg.h/varargs.h).
  401.      */
  402.     if (m_arg->len > 4) accumulate_size = (accumulate_size + 7) & -8;
  403.     m_arg->offset = accumulate_size;
  404.     accumulate_size = (accumulate_size + m_arg->len + 3) & -4;
  405.     m_arg->contents = VALUE_CONTENTS(arg);
  406.   }
  407.   accumulate_size = (accumulate_size + 7) & (-8);
  408.   if (accumulate_size < 16) accumulate_size = 16; 
  409.   sp -= accumulate_size;
  410.   for (i = nargs; m_arg--, --i >= 0; )
  411.     write_memory(sp + m_arg->offset, m_arg->contents, m_arg->len);
  412.   if (struct_return) {
  413.     buf = struct_addr;
  414.     write_memory(sp, &buf, sizeof(CORE_ADDR));
  415. }
  416.   return sp;
  417. }
  418.  
  419. /* MASK(i,j) == (1<<i) + (1<<(i+1)) + ... + (1<<j)). Assume i<=j<31. */
  420. #define MASK(i,j) ((1 << (j)+1)-1 ^ (1 << (i))-1)
  421.  
  422. void
  423. mips_push_dummy_frame()
  424. {
  425.   int ireg;
  426.   struct linked_proc_info *link = (struct linked_proc_info*)
  427.       xmalloc(sizeof(struct linked_proc_info));
  428.   mips_extra_func_info_t proc_desc = &link->info;
  429.   CORE_ADDR sp = read_register (SP_REGNUM);
  430.   CORE_ADDR save_address;
  431.   REGISTER_TYPE buffer;
  432.   link->next = linked_proc_desc_table;
  433.   linked_proc_desc_table = link;
  434. #define PUSH_FP_REGNUM 16 /* must be a register preserved across calls */
  435. #define GEN_REG_SAVE_MASK MASK(1,16)|MASK(24,28)|(1<<31)
  436. #define GEN_REG_SAVE_COUNT 22
  437. #define FLOAT_REG_SAVE_MASK MASK(0,19)
  438. #define FLOAT_REG_SAVE_COUNT 20
  439. #define SPECIAL_REG_SAVE_COUNT 4
  440.   /*
  441.    * The registers we must save are all those not preserved across
  442.    * procedure calls. Dest_Reg (see tm-mips.h) must also be saved.
  443.    * In addition, we must save the PC, and PUSH_FP_REGNUM.
  444.    * (Ideally, we should also save MDLO/-HI and FP Control/Status reg.)
  445.    *
  446.    * Dummy frame layout:
  447.    *  (high memory)
  448.    *     Saved PC
  449.    *    Saved MMHI, MMLO, FPC_CSR
  450.    *    Saved R31
  451.    *    Saved R28
  452.    *    ...
  453.    *    Saved R1
  454.    *    Saved D18 (i.e. F19, F18)
  455.    *    ...
  456.    *    Saved D0 (i.e. F1, F0)
  457.    *    CALL_DUMMY (subroutine stub; see m-mips.h)
  458.    *    Parameter build area (not yet implemented)
  459.    *  (low memory)
  460.    */
  461.   PROC_REG_MASK(proc_desc) = GEN_REG_SAVE_MASK;
  462.   PROC_FREG_MASK(proc_desc) = FLOAT_REG_SAVE_MASK;
  463.   PROC_REG_OFFSET(proc_desc) = /* offset of (Saved R31) from FP */
  464.       -sizeof(long) - 4 * SPECIAL_REG_SAVE_COUNT;
  465.   PROC_FREG_OFFSET(proc_desc) = /* offset of (Saved D18) from FP */
  466.       -sizeof(double) - 4 * (SPECIAL_REG_SAVE_COUNT + GEN_REG_SAVE_COUNT);
  467.   /* save general registers */
  468.   save_address = sp + PROC_REG_OFFSET(proc_desc);
  469.   for (ireg = 32; --ireg >= 0; )
  470.     if (PROC_REG_MASK(proc_desc) & (1 << ireg))
  471.       {
  472.     buffer = read_register (ireg);
  473.     write_memory (save_address, &buffer, sizeof(REGISTER_TYPE));
  474.     save_address -= 4;
  475.       }
  476.   /* save floating-points registers */
  477.   save_address = sp + PROC_FREG_OFFSET(proc_desc);
  478.   for (ireg = 32; --ireg >= 0; )
  479.     if (PROC_FREG_MASK(proc_desc) & (1 << ireg))
  480.       {
  481.     buffer = read_register (ireg);
  482.     write_memory (save_address, &buffer, 4);
  483.     save_address -= 4;
  484.       }
  485.   write_register (PUSH_FP_REGNUM, sp);
  486.   PROC_FRAME_REG(proc_desc) = PUSH_FP_REGNUM;
  487.   PROC_FRAME_OFFSET(proc_desc) = 0;
  488.   buffer = read_register (PC_REGNUM);
  489.   write_memory (sp - 4, &buffer, sizeof(REGISTER_TYPE));
  490.   buffer = read_register (HI_REGNUM);
  491.   write_memory (sp - 8, &buffer, sizeof(REGISTER_TYPE));
  492.   buffer = read_register (LO_REGNUM);
  493.   write_memory (sp - 12, &buffer, sizeof(REGISTER_TYPE));
  494.   buffer = read_register (FCRCS_REGNUM);
  495.   write_memory (sp - 16, &buffer, sizeof(REGISTER_TYPE));
  496.   sp -= 4 * (GEN_REG_SAVE_COUNT+FLOAT_REG_SAVE_COUNT+SPECIAL_REG_SAVE_COUNT);
  497.   write_register (SP_REGNUM, sp);
  498.   PROC_LOW_ADDR(proc_desc) = sp - CALL_DUMMY_SIZE + CALL_DUMMY_START_OFFSET;
  499.   PROC_HIGH_ADDR(proc_desc) = sp;
  500.   SET_PROC_DESC_IS_DUMMY(proc_desc);
  501.   PROC_PC_REG(proc_desc) = RA_REGNUM;
  502. }
  503.  
  504. void
  505. mips_pop_frame()
  506. { register int regnum;
  507.   FRAME frame = get_current_frame ();
  508.   CORE_ADDR new_sp = frame->frame;
  509.   mips_extra_func_info_t proc_desc = (mips_extra_func_info_t)frame->proc_desc;
  510.   if (PROC_DESC_IS_DUMMY(proc_desc))
  511.     {
  512.       struct linked_proc_info **ptr = &linked_proc_desc_table;;
  513.       for (; &ptr[0]->info != proc_desc; ptr = &ptr[0]->next )
  514.       if (ptr[0] == NULL) abort();
  515.       *ptr = ptr[0]->next;
  516.       free (ptr[0]);
  517.       write_register (HI_REGNUM, read_memory_integer(new_sp - 8, 4));
  518.       write_register (LO_REGNUM, read_memory_integer(new_sp - 12, 4));
  519.       write_register (FCRCS_REGNUM, read_memory_integer(new_sp - 16, 4));
  520.     }
  521.   write_register (PC_REGNUM, FRAME_SAVED_PC(frame));
  522.   if (frame->proc_desc) {
  523.     for (regnum = 32; --regnum >= 0; )
  524.       if (PROC_REG_MASK(proc_desc) & (1 << regnum))
  525.     write_register (regnum,
  526.           read_memory_integer (frame->saved_regs->regs[regnum], 4));
  527.     for (regnum = 64; --regnum >= 32; )
  528.       if (PROC_FREG_MASK(proc_desc) & (1 << regnum))
  529.     write_register (regnum,
  530.           read_memory_integer (frame->saved_regs->regs[regnum], 4));
  531.   }
  532.   write_register (SP_REGNUM, new_sp);
  533.   flush_cached_frames ();
  534.   set_current_frame (create_new_frame (new_sp, read_pc ()));
  535. }
  536.  
  537. static
  538. mips_print_register(regnum, all)
  539.      int regnum, all;
  540. {
  541.       unsigned char raw_buffer[8];
  542.       REGISTER_TYPE val;
  543.  
  544.       read_relative_register_raw_bytes (regnum, raw_buffer);
  545.  
  546.       if (!(regnum & 1) && regnum >= FP0_REGNUM && regnum < FP0_REGNUM+32) {
  547.       read_relative_register_raw_bytes (regnum+1, raw_buffer+4);
  548.       printf_filtered ("(d%d: ", regnum&31);
  549.       val_print (builtin_type_double, raw_buffer, 0,
  550.              stdout, 0, 1, 0, Val_pretty_default);
  551.       printf_filtered ("); ", regnum&31);
  552.       }
  553.       fputs_filtered (reg_names[regnum], stdout);
  554. #ifndef NUMERIC_REG_NAMES
  555.       if (regnum < 32)
  556.       printf_filtered ("(r%d): ", regnum);
  557.       else
  558. #endif
  559.       printf_filtered (": ");
  560.  
  561.       /* If virtual format is floating, print it that way.  */
  562.       if (TYPE_CODE (REGISTER_VIRTUAL_TYPE (regnum)) == TYPE_CODE_FLT
  563.       && ! INVALID_FLOAT (raw_buffer, REGISTER_VIRTUAL_SIZE(regnum))) {
  564.       val_print (REGISTER_VIRTUAL_TYPE (regnum), raw_buffer, 0,
  565.              stdout, 0, 1, 0, Val_pretty_default);
  566.       }
  567.       /* Else print as integer in hex.  */
  568.       else
  569.     {
  570.       long val;
  571.  
  572.       bcopy (raw_buffer, &val, sizeof (long));
  573.       if (val == 0)
  574.         printf_filtered ("0");
  575.       else if (all)
  576.         printf_filtered (local_hex_format(), val);
  577.       else
  578.         printf_filtered ("%s=%d", local_hex_string(val), val);
  579.     }
  580. }
  581.  
  582. /* Replacement for generic do_registers_info.  */
  583. mips_do_registers_info (regnum, fpregs)
  584.      int regnum;
  585.      int fpregs;
  586. {
  587.   if (regnum != -1) {
  588.       mips_print_register (regnum, 0);
  589.       printf_filtered ("\n");
  590.   }
  591.   else {
  592.       for (regnum = 0; regnum < NUM_REGS; ) {
  593.       if ((!fpregs) && regnum >= FP0_REGNUM && regnum <= FCRIR_REGNUM) {
  594.         regnum++;
  595.         continue;
  596.       }
  597.       mips_print_register (regnum, 1);
  598.       regnum++;
  599.       if ((regnum & 3) == 0 || regnum == NUM_REGS)
  600.           printf_filtered (";\n");
  601.       else
  602.           printf_filtered ("; ");
  603.       }
  604.   }
  605. }
  606. /* Return number of args passed to a frame. described by FIP.
  607.    Can return -1, meaning no way to tell.  */
  608.  
  609. mips_frame_num_args(fip)
  610.     FRAME fip;
  611. {
  612. #if 0
  613.     struct chain_info_t *p;
  614.  
  615.     p = mips_find_cached_frame(FRAME_FP(fip));
  616.     if (p->valid)
  617.         return p->the_info.numargs;
  618. #endif
  619.     return -1;
  620. }
  621.  
  622.  
  623. /* Bad floats: Returns 0 if P points to a valid IEEE floating point number,
  624.    1 if P points to a denormalized number or a NaN. LEN says whether this is
  625.    a single-precision or double-precision float */
  626. #define SINGLE_EXP_BITS  8
  627. #define DOUBLE_EXP_BITS 11
  628. int
  629. isa_NAN(p, len)
  630.      int *p, len;
  631. {
  632.   int exponent;
  633.   if (len == 4)
  634.     {
  635.       exponent = *p;
  636.       exponent = exponent << 1 >> (32 - SINGLE_EXP_BITS - 1);
  637.       return ((exponent == -1) || (! exponent && *p));
  638.     }
  639.   else if (len == 8)
  640.     {
  641.       exponent = *(p+1);
  642.       exponent = exponent << 1 >> (32 - DOUBLE_EXP_BITS - 1);
  643.       return ((exponent == -1) || (! exponent && *p * *(p+1)));
  644.     }
  645.   else return 1;
  646. }
  647.  
  648. /* To skip prologues, I use this predicate. Returns either PC
  649.    itself if the code at PC does not look like a function prologue,
  650.    PC+4 if it does (our caller does not need anything more fancy). */
  651.  
  652. CORE_ADDR mips_skip_prologue(pc)
  653.      CORE_ADDR pc;
  654. {
  655.     struct symbol *f;
  656.     struct block *b;
  657.     unsigned long inst;
  658.  
  659.     /* For -g modules and most functions anyways the
  660.        first instruction adjusts the stack. */
  661.     inst = read_memory_integer(pc, 4);
  662.     if ((inst & 0xffff0000) == 0x27bd0000)
  663.     return pc + 4;
  664.  
  665.     /* Well, it looks like a frameless. Let's make sure.
  666.        Note that we are not called on the current PC,
  667.        but on the function`s start PC, and I have definitely
  668.        seen optimized code that adjusts the SP quite later */
  669.     b = block_for_pc(pc);
  670.     if (!b) return pc;
  671.  
  672.     f = lookup_symbol(".gdbinfo.", b, LABEL_NAMESPACE, 0, NULL);
  673.     if (!f) return pc;
  674.     /* Ideally, I would like to use the adjusted info
  675.        from mips_frame_info(), but for all practical
  676.        purposes it will not matter (and it would require
  677.        a different definition of SKIP_PROLOGUE())
  678.  
  679.        Actually, it would not hurt to skip the storing
  680.        of arguments on the stack as well. */
  681.     if (((struct mips_extra_func_info *)f->value.value)->framesize)
  682.     return pc + 4;
  683.  
  684.     return pc;
  685. }
  686.